#include "software.h"
#include <stdlib.h>
#include <glib-object.h>
#include <stdbool.h>

typedef struct _SoftwareSoftware {
  GObject parent_instance;

  gchar *class;

  gint64 id;
  gint64 parentID;

  gint port;
  gint type;
  gint test;

  gboolean status;

  gfloat latitude;
  gfloat longitude;
  gfloat altitude;
  gfloat yaw;

  gchar *ip;
  gchar *name;
  gchar *typeDescribe;
  gchar *dbVersion;

  gchar *testFile;
//ros
  gchar *nodeName;
  gchar *frameId;
  gchar *subTopic;
  gchar *pubTopic;

  gpointer intra;

  GObject *son;
  GObject *next;
  GObject *prev;
} SoftwareSoftware;
enum {
  PROP_0,
  PROP_CLASS,
  PROP_ID, PROP_PARENT_ID,
  PROP_PORT, PROP_TYPE, PROP_TEST,
  PROP_STATUS,
  PROP_LATITUDE, PROP_LONGITUDE, PROP_ALTITUDE, PROP_YAW,
  PROP_IP,
  PROP_NAME, PROP_TYPE_DESCRIBE, PROP_DB_VERSION,
  PROP_TEST_FILE,
  PROP_NODE_NAME, PROP_FRAME_ID, PROP_SUB_TOPIC, PROP_PUB_TOPIC,
  PROP_INTRA,
  PROP_SON, PROP_NEXT, PROP_PREV,
  N_PROPERTIES };

static GParamSpec *properties[N_PROPERTIES] = { NULL, };

G_DEFINE_TYPE(SoftwareSoftware, software_software, G_TYPE_OBJECT)
//int64
static void software_software_set_id(SoftwareSoftware *obj, gint64    value)
{
  if (obj->id != value) {
      obj->id = value;

      g_assert(properties[PROP_ID] != NULL);
      g_object_notify_by_pspec(G_OBJECT(obj), properties[PROP_ID]);
    }
}
static void
software_software_set_parentID(SoftwareSoftware *obj,
                     gint64    value)
{
  if (obj->parentID != value)
    {
      obj->parentID = value;

      g_assert(properties[PROP_PARENT_ID] != NULL);
      g_object_notify_by_pspec(G_OBJECT(obj), properties[PROP_PARENT_ID]);
    }
}
//int
static void
software_software_set_port(SoftwareSoftware *obj,
                     gint        port)
{
  if (obj->port != port)
    {
      obj->port = port;

      g_assert(properties[PROP_PORT] != NULL);
      g_object_notify_by_pspec(G_OBJECT(obj), properties[PROP_PORT]);
    }
}
static void
software_software_set_type(SoftwareSoftware *obj,
                     gint    value)
{
  if (obj->type != value)
    {
      obj->type = value;

      g_assert(properties[PROP_TYPE] != NULL);
      g_object_notify_by_pspec(G_OBJECT(obj), properties[PROP_TYPE]);
    }
}
//boolean
static void
software_software_set_status(SoftwareSoftware *obj,
                     gboolean    status)
{
  status = !!status;

  if (obj->status != status)
    {
      obj->status = status;

      g_assert(properties[PROP_STATUS] != NULL);
      g_object_notify_by_pspec(G_OBJECT(obj), properties[PROP_STATUS]);
    }
}
//char
static void
software_software_set_name(SoftwareSoftware  *obj,
                     const gchar *name)
{
  if (g_strcmp0(obj->name, name) != 0)
    {
      g_free(obj->name);
      obj->name = g_strdup(name);

      g_assert(properties[PROP_NAME] != NULL);
      g_object_notify_by_pspec(G_OBJECT(obj), properties[PROP_NAME]);
    }
}
static void
software_software_set_class(SoftwareSoftware  *obj, const gchar *value)
{
  if (g_strcmp0(obj->class, value) != 0)
    {
      g_free(obj->class);
      obj->class = g_strdup(value);

      g_assert(properties[PROP_CLASS] != NULL);
      g_object_notify_by_pspec(G_OBJECT(obj), properties[PROP_CLASS]);
    }
}
static void
software_software_set_intra(SoftwareSoftware  *obj,
                      gpointer value)
{
    obj->intra = value;
}
//object
static void
software_software_set_next(SoftwareSoftware  *obj,
                      gpointer next)
{
    obj->next = next;
}

static void
software_software_set_son(SoftwareSoftware  *obj,
                      gpointer son)
{
    obj->son = son;
}
static void
software_software_set_prev(SoftwareSoftware  *obj,
                      gpointer value)
{
    obj->prev = value;
}

static void
software_software_finalize(GObject *gobject)
{
  SoftwareSoftware *self = (SoftwareSoftware *) gobject;

  if (self->next)
    g_object_unref(self->next);
  if (self->son)
    g_object_unref(self->son);

  if (self->ip)
    g_free(self->ip);
  if (self->name)
    g_free(self->name);
  if (self->typeDescribe)
    g_free(self->typeDescribe);
  if (self->dbVersion)
    g_free(self->dbVersion);
  if (self->class)
    g_free(self->class);

  g_object_notify(gobject, "port");
  g_object_notify_by_pspec(gobject, properties[PROP_STATUS]);

  G_OBJECT_CLASS(software_software_parent_class)->finalize(gobject);
}

static void
software_software_set_property(GObject *gobject,
                          guint prop_id,
                          const GValue *value,
                          GParamSpec *pspec)
{
  SoftwareSoftware *tobj = (SoftwareSoftware *) gobject;

  g_assert_cmpint(prop_id, !=, 0);
  g_assert_cmpint(prop_id, !=, N_PROPERTIES);
  g_assert(pspec == properties[prop_id]);

  switch (prop_id)
    {
    case PROP_ID:
      software_software_set_id(tobj, g_value_get_int64(value));
      break;
    case PROP_PARENT_ID:
      software_software_set_parentID(tobj, g_value_get_int64(value));
      break;

    case PROP_STATUS:
      software_software_set_status(tobj, g_value_get_boolean(value));
      break;

    case PROP_LATITUDE:
      tobj->latitude = g_value_get_float(value);
      break;
    case PROP_LONGITUDE:
      tobj->longitude = g_value_get_float(value);
      break;
    case PROP_ALTITUDE:
      tobj->altitude = g_value_get_float(value);
      break;
    case PROP_YAW:
      tobj->yaw = g_value_get_float(value);
      break;


    case PROP_PORT:
      software_software_set_port(tobj, g_value_get_int(value));
      break;
    case PROP_TYPE:
      software_software_set_type(tobj, g_value_get_int(value));
      break;
    case PROP_TEST:
      tobj->test = g_value_get_int(value);
      break;

    case PROP_IP:
      if (tobj->ip)
        free(tobj->ip);
      tobj->ip = g_strdup(g_value_get_string(value));
      break;
    case PROP_NAME:
      software_software_set_name(tobj, g_value_get_string(value));
      break;
    case PROP_CLASS:
      software_software_set_class(tobj, g_value_get_string(value));
      break;
    case PROP_TYPE_DESCRIBE:
      if (g_strcmp0(tobj->typeDescribe,
            g_value_get_string(value)) != 0) {
        g_free(tobj->typeDescribe);
        tobj->typeDescribe = g_strdup(g_value_get_string(value));
      }
      break;
    case PROP_DB_VERSION:
      if (g_strcmp0(tobj->dbVersion,
            g_value_get_string(value)) != 0) {
        g_free(tobj->dbVersion);
        tobj->dbVersion = g_strdup(g_value_get_string(value));
      }
      break;

    case PROP_TEST_FILE:
      if (g_strcmp0(tobj->testFile,
            g_value_get_string(value)) != 0) {
        g_free(tobj->testFile);
        tobj->testFile = g_strdup(g_value_get_string(value));
      }
      break;

    case PROP_NODE_NAME:
      if (g_strcmp0(tobj->nodeName,
            g_value_get_string(value)) != 0) {
        g_free(tobj->nodeName);
        tobj->nodeName = g_strdup(g_value_get_string(value));
      }
      break;
    case PROP_FRAME_ID:
      if (g_strcmp0(tobj->frameId,
            g_value_get_string(value)) != 0) {
        g_free(tobj->frameId);
        tobj->frameId = g_strdup(g_value_get_string(value));
      }
      break;
    case PROP_SUB_TOPIC:
      if (g_strcmp0(tobj->subTopic,
            g_value_get_string(value)) != 0) {
        g_free(tobj->subTopic);
        tobj->subTopic = g_strdup(g_value_get_string(value));
      }
      break;
    case PROP_PUB_TOPIC:
      if (g_strcmp0(tobj->pubTopic,
            g_value_get_string(value)) != 0) {
        g_free(tobj->pubTopic);
        tobj->pubTopic = g_strdup(g_value_get_string(value));
      }
      break;

    case PROP_INTRA:
      software_software_set_intra(tobj, g_value_get_pointer(value));
      break;

    case PROP_NEXT:
      software_software_set_next(tobj, g_value_get_pointer(value));
      break;
    case PROP_SON:
      software_software_set_son(tobj, g_value_get_pointer(value));
      break;
    case PROP_PREV:
      software_software_set_prev(tobj, g_value_get_pointer(value));
      break;

    default:
      g_assert_not_reached();
    }
}

static void
software_software_get_property(GObject *gobject,
                          guint prop_id,
                          GValue *value,
                          GParamSpec *pspec)
{
  SoftwareSoftware *tobj = (SoftwareSoftware *) gobject;

  g_assert_cmpint(prop_id, !=, 0);
  g_assert_cmpint(prop_id, !=, N_PROPERTIES);
  g_assert(pspec == properties[prop_id]);

  switch (prop_id)
    {
    case PROP_ID:
      g_value_set_int64(value, tobj->id);
      break;
    case PROP_PARENT_ID:
      g_value_set_int64(value, tobj->parentID);
      break;

    case PROP_PORT:
      g_value_set_int(value, tobj->port);
      break;
    case PROP_TYPE:
      g_value_set_int(value, tobj->type);
      break;
    case PROP_TEST:
      g_value_set_int(value, tobj->test);
      break;

    case PROP_STATUS:
      g_value_set_boolean(value, tobj->status);
      break;

    case PROP_LATITUDE:
      g_value_set_float(value, tobj->latitude);
      break;
    case PROP_LONGITUDE:
      g_value_set_float(value, tobj->longitude);
      break;
    case PROP_ALTITUDE:
      g_value_set_float(value, tobj->altitude);
      break;
    case PROP_YAW:
      g_value_set_float(value, tobj->yaw);
      break;


    case PROP_IP:
      g_value_set_string(value, tobj->ip);
      break;
    case PROP_NAME:
      g_value_set_string(value, tobj->name);
      break;
    case PROP_CLASS:
      g_value_set_string(value, tobj->class);
      break;
    case PROP_TYPE_DESCRIBE:
      g_value_set_string(value, tobj->typeDescribe);
      break;
    case PROP_DB_VERSION:
      g_value_set_string(value, tobj->dbVersion);
      break;

    case PROP_TEST_FILE:
      g_value_set_string(value, tobj->testFile);
      break;

    case PROP_NODE_NAME:
      g_value_set_string(value, tobj->nodeName);
      break;
    case PROP_FRAME_ID:
      g_value_set_string(value, tobj->frameId);
      break;
    case PROP_SUB_TOPIC:
      g_value_set_string(value, tobj->subTopic);
      break;
    case PROP_PUB_TOPIC:
      g_value_set_string(value, tobj->pubTopic);
      break;

    case PROP_INTRA:
      g_value_set_pointer(value, tobj->intra);
      break;

    case PROP_NEXT:
      g_value_set_pointer(value, tobj->next);
      break;
    case PROP_SON:
      g_value_set_pointer(value, tobj->son);
      break;
    case PROP_PREV:
      g_value_set_pointer(value, tobj->prev);
      break;
    default:
      g_error("%d\n", prop_id);
      g_assert_not_reached();
    }
}

static void
software_software_class_init(SoftwareSoftwareClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS(klass);

  properties[PROP_ID] = g_param_spec_int64("id", "id", "Id",
      G_MININT64, G_MAXINT64, 0, G_PARAM_READWRITE);
  properties[PROP_PARENT_ID] = g_param_spec_int64(
      "parentID", "parentID", "ParentId",
      -1, G_MAXINT64, 0, G_PARAM_READWRITE);

  properties[PROP_STATUS] = g_param_spec_boolean("status", "Status", "Status",
      FALSE, G_PARAM_READWRITE);

  properties[PROP_PORT] = g_param_spec_int("port", "port", "port",
      -1, G_MAXINT, 0, G_PARAM_READWRITE);
  properties[PROP_TYPE] = g_param_spec_int("type", "type", "type",
      -1, G_MAXINT, 0, G_PARAM_READWRITE);
  properties[PROP_TEST] = g_param_spec_int("test", "Test", "test",
      -1, G_MAXINT, 0, G_PARAM_READWRITE);

  properties[PROP_TYPE_DESCRIBE] = g_param_spec_string(
      "typeDescribe", "TypeDescribe", "type describe",
      NULL, G_PARAM_READWRITE);
  properties[PROP_DB_VERSION] = g_param_spec_string(
      "dbVersion", "DbVersion", "db version",
      NULL, G_PARAM_READWRITE);
  properties[PROP_IP] = g_param_spec_string("ip", "Ip", "ip",
      NULL, G_PARAM_READWRITE);
  properties[PROP_NAME] = g_param_spec_string("name", "Name", "NAME",
      NULL, G_PARAM_READWRITE);
  properties[PROP_CLASS] = g_param_spec_string(
      "class", "Class", "CLASS",
      NULL, G_PARAM_READWRITE);

  properties[PROP_TEST_FILE] = g_param_spec_string(
      "testFile", "TestFile", "test file",
      NULL, G_PARAM_READWRITE);

  properties[PROP_NODE_NAME] = g_param_spec_string(
      "nodeName", "NodeName", "node name",
      NULL, G_PARAM_READWRITE);
  properties[PROP_FRAME_ID] = g_param_spec_string(
      "frameId", "FrameId", "frame id",
      NULL, G_PARAM_READWRITE);
  properties[PROP_SUB_TOPIC] = g_param_spec_string(
      "subTopic", "SubTopic", "subscribe topic",
      NULL, G_PARAM_READWRITE);
  properties[PROP_PUB_TOPIC] = g_param_spec_string(
      "pubTopic", "PubTopic", "publish topic",
      NULL, G_PARAM_READWRITE);

  properties[PROP_INTRA] = g_param_spec_pointer("intra", "intra", "intra",
      G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);

  properties[PROP_SON] = g_param_spec_pointer("son", "son", "son",
      G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
  properties[PROP_NEXT] = g_param_spec_pointer("next", "next", "next",
      G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
  properties[PROP_PREV] = g_param_spec_pointer("prev", "Prev", "prev",
      G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);

  properties[PROP_LATITUDE] = g_param_spec_float(
      "latitude", "Latitude", "latitude",
      -G_MAXFLOAT, G_MAXFLOAT, 0, G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
  properties[PROP_LONGITUDE] = g_param_spec_float(
      "longitude", "Longitude", "longitude",
      -G_MAXFLOAT, G_MAXFLOAT, 0, G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
  properties[PROP_ALTITUDE] = g_param_spec_float(
      "altitude", "Altitude", "altitude",
      -G_MAXFLOAT, G_MAXFLOAT, 0, G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
  properties[PROP_YAW] = g_param_spec_float(
      "yaw", "Yaw", "yaw",
      -G_MAXFLOAT, G_MAXFLOAT, 0, G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);

  gobject_class->set_property = software_software_set_property;
  gobject_class->get_property = software_software_get_property;
  gobject_class->finalize = software_software_finalize;

  g_object_class_install_properties(gobject_class, N_PROPERTIES, properties);
}

static void
software_software_init(SoftwareSoftware *self)
{
  self->status = FALSE;
}

SoftwareSoftware *software_softwares_get_object(SoftwareSoftware *gobject,
                          const gchar *name,
                          gpointer value)
{
  SoftwareSoftware *tobj = gobject;
  while (tobj) {
    if (!strcmp(name, "id")) {
      if (tobj->id == *(gint64*)(value)) {
        break;
      }
    } else if (!strcmp(name, "name")) {
      if (tobj->name) {
        if (!strcmp(tobj->name, value)) {
          break;
        }
      }
    }
    tobj = (SoftwareSoftware *)tobj->next;
  }
  return tobj;
}
SoftwareSoftware *software_software_new(void)
{
  return g_object_new(SOFTWARE_SOFTWARE_TYPE, NULL);
}
